/**
 * 
 */
package com.ezops.controller;

import java.io.IOException;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.ezops.dao.facade.DataTransferFacade;
import com.ezops.dao.facade.ISystemPropertyFacade;
import com.ezops.dao.facade.ITradeExceptionFacade;
import com.ezops.models.SystemProperty;
import com.ezops.models.User;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * @author Administrator
 * 
 */
@Controller
public class LoginLogoutController {

	@Autowired
	private ITradeExceptionFacade tradeExceptionFacade;
	
	@Autowired
	@Qualifier("UserDataTransferFacade")
	private DataTransferFacade<User> userFacade;
	@Autowired
	private ISystemPropertyFacade systemPropertyFacade;
	SystemProperty property = new SystemProperty();

	final static Logger logger = LoggerFactory
			.getLogger(SessionManagementController.class);

	/**
	 * 
	 * @param jsonbody
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = "/login")
	@ResponseBody
	public String userLogin(@RequestBody String jsonbody,
			HttpServletRequest request, HttpServletResponse response) {

		String jsonText = "";

		try {

			logger.debug("User JSON :      \n" + jsonbody);

			ObjectMapper mapper = new ObjectMapper();
			User authUser = mapper.readValue(jsonbody, User.class);
			// // Finds the user by id
			SecurityUtils.getSubject().login(
					new UsernamePasswordToken(authUser.getId(), authUser
							.getPassword()));
			manageSession(request, response);
			request.getSession().setAttribute("user",
					SecurityUtils.getSubject().getPrincipal());

			response.setStatus(HttpServletResponse.SC_OK);
			jsonText = "valid";
			
			property.setName("asofdate");
			SystemProperty asofdate = systemPropertyFacade.getPropertyValue(property);
			Session session = SecurityUtils.getSubject().getSession();
			session.setAttribute("asofdate", asofdate.getValue());

		} catch (AuthenticationException ae) {
			try {
				response.sendError(HttpServletResponse.SC_UNAUTHORIZED,
						ae.getMessage());
				// "Not Authorized UserID and/or password invalid");
			} catch (IOException e) {

				e.printStackTrace();
			}
			jsonText = "invalid";
		} catch (Throwable e) {
			e.printStackTrace();
			logger.error(e.getMessage());
			response.setStatus(500);
			jsonText = "{\"ERROR_CODE\":\"" + e.getMessage() + "\"}";
			// Set the exception and send it back to the caller

		} finally {
		}
		// String fallbackUrl = "redirect:/";
		//
		// try {
		// WebUtils.redirectToSavedRequest(request, response, fallbackUrl);
		// } catch (IOException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		return jsonText;
	}

	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public String login(Model model){

		model.addAttribute("message", "from Login");
		model.addAttribute("title", "EZOPS | Login");
		return "login";
	}

	/**
	 * Rest call for logging out.
	 */
	@RequestMapping(method = RequestMethod.GET, value = "/logout")
	public String userLogout() {
		if (SecurityUtils.getSubject() != null
				&& SecurityUtils.getSubject().isAuthenticated()) {
			SecurityUtils.getSubject().logout();
		}
		return "redirect:/login";
	}

	@RequestMapping(value="/login/error", method=RequestMethod.GET)
	public String toLogin(Model model){
		model.addAttribute("message", "error");
		return "login";
	}

	@RequestMapping(value = "/UploadForm", method = RequestMethod.GET)
	public String getForms(Model model) {
		model.addAttribute("message", "error");
		System.out.println("loading forms");

		return "UploadForm";
	}

	@RequestMapping(value = "/referencedata", method = RequestMethod.GET)
	public String referenceData(Model model, HttpServletRequest request) {

		// System.out.println("To reference");
		model.addAttribute("message", "Reference Data");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());

		return "ReferenceData";
	}

	@RequestMapping(value = "/userManagement", method = RequestMethod.GET)
	public String userManagement(Model model, HttpServletRequest request) {

		// System.out.println("To reference");
		model.addAttribute("message", "User Management");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());

		return "usermanagement";
	}

	/**
	 * Commented for US Bank demo
	 * 
	 * @param model
	 * @param request
	 * @return
	 */
	/*
	 * @RequestMapping(value="/trademonitor", method=RequestMethod.GET) public
	 * String tradeMonitor(Model model,HttpServletRequest request){
	 * 
	 * System.out.println("To Trademonitor"); model.addAttribute("message",
	 * "File Monitor"); User
	 * userObj=(User)request.getSession().getAttribute("user");
	 * model.addAttribute
	 * ("user",userObj.getFirstName()+" "+userObj.getLastName());
	 * model.addAttribute("userId",userObj.getUserId());
	 * model.addAttribute("pic",userObj.getProfilePic());
	 * 
	 * return "TradeMonitor"; }
	 */
	@RequestMapping(value = "/dashboard", method = RequestMethod.GET)
	public String dashboard(Model model, HttpServletRequest request) {
		//property.setName("asofdate");
		//SystemProperty asofdate = systemPropertyFacade.getPropertyValue(property);
		// System.out.println("To dashboard");
		model.addAttribute("message", "Dashboard ");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());
		//System.out.println("asofdate.getValue()>>>>"+asofdate.getValue());
		model.addAttribute("asofdate", SecurityUtils.getSubject().getSession().getAttribute("asofdate"));

		return "dashboard";
	}

	@RequestMapping(value = "/fieldMapping", method = RequestMethod.GET, headers = "Accept=application/json")
	public String fieldMapping(Model model, HttpServletRequest request) {
		model.addAttribute("message", "Field Mapping");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());
		return "fieldmapping";
	}

	/**
	 * Mapping changed for US bank demo
	 * 
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/trademonitor", method = RequestMethod.GET, headers = "Accept=application/json")
	public String exceptionReport(Model model, HttpServletRequest request) {
		//model.addAttribute("message", "Exception Report");
		model.addAttribute("message", "Trade Monitor");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());
		return "trademonitor";
	}

	@RequestMapping(value = "/validationRule", method = RequestMethod.GET, headers = "Accept=application/json")
	public String validationRule(Model model, HttpServletRequest request) {
		model.addAttribute("message", "Validation Rule");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());
		return "validationrule";
	}

	@RequestMapping(value = "/tradeprocessingreport", method = RequestMethod.GET)
	public String tradeProcessingReport(Model model, HttpServletRequest request) {
		model.addAttribute("message", "Trade Processing Report");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());
		model.addAttribute("asofdate", SecurityUtils.getSubject().getSession().getAttribute("asofdate"));
		return "tradeprocessingreport";
	}

	@RequestMapping(value = "/profitandlossreport", method = RequestMethod.GET)
	public String profitAndLossReport(Model model, HttpServletRequest request) {
		model.addAttribute("message", "Profit & Loss Report");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());
		model.addAttribute("asofdate", SecurityUtils.getSubject().getSession().getAttribute("asofdate"));
		return "profitandlossreport";
	}

	@RequestMapping(value = "/riskreport", method = RequestMethod.GET)
	public String riskReport(Model model, HttpServletRequest request) {
		model.addAttribute("message", "Risk Report");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());
		model.addAttribute("asofdate", SecurityUtils.getSubject().getSession().getAttribute("asofdate"));
		return "riskreport";
	}

	@RequestMapping(value = "/collateralreport", method = RequestMethod.GET)
	public String collateralReport(Model model, HttpServletRequest request) {
		model.addAttribute("message", "Collateral Report");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());
		model.addAttribute("asofdate", SecurityUtils.getSubject().getSession().getAttribute("asofdate"));
		return "collateralreport";
	}

	@RequestMapping(value = "/cashmanagementreport", method = RequestMethod.GET)
	public String cashManagementReport(Model model, HttpServletRequest request) {
		model.addAttribute("message", "Cash Management Report");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());
		model.addAttribute("asofdate", SecurityUtils.getSubject().getSession().getAttribute("asofdate"));
		return "cashmanagementreport";
	}

	/**
	 * Open the file monitor screen.
	 * 
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/filemonitor", method = RequestMethod.GET)
	public String fileMonitor(Model model, HttpServletRequest request) {

		// System.out.println("To Filemonitor");
		model.addAttribute("message", "File Monitor");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());

		return "filemonitor";

	}

	/**
	 * Open the file monitor screen.
	 * 
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/lifecycleevent", method = RequestMethod.GET)
	public String lifeCycleEvent(Model model, HttpServletRequest request) {

		model.addAttribute("message", "Life Cycle Event");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());

		return "lifecycleevent";

	}

	/**
	 * Open the file monitor screen.
	 * 
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/clientddquestionnaire", method = RequestMethod.GET)
	public String ClientDDQuestionnaire(Model model, HttpServletRequest request) {

		// System.out.println("To Filemonitor");
		model.addAttribute("message", "Client DD Questionnaire");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());

		return "ClientDDQuestionnaire";

	}

	/**
	 * Open the Client Detail screen.
	 * 
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/clientdetails", method = RequestMethod.GET)
	public String ClientDetails(Model model, HttpServletRequest request) {

		// System.out.println("To Filemonitor");
		model.addAttribute("message", "Client Details");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());

		return "ClientDetails";

	}
	
	/**
	 * Mapping changed for US bank demo
	 * 
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/userdashboard", method = RequestMethod.GET, headers = "Accept=application/json")
	public String userDashboard(Model model, HttpServletRequest request) {
		//model.addAttribute("message", "Exception Report");
		model.addAttribute("message", "User Dashboard");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());
		return "userdashboard";
	}
	
	/**
	 * Mapping changed for US bank demo
	 * 
	 * @param model
	 * @param request
	 * @return
	 */
	@RequestMapping(value = "/exceptionResolution", method = RequestMethod.GET, headers = "Accept=application/json")
	public String exceptionResolution(Model model, HttpServletRequest request) {
		//model.addAttribute("message", "Exception Report");
		model.addAttribute("message", "Exception Resolution");
		User userObj = (User) request.getSession().getAttribute("user");
		model.addAttribute("user",
				userObj.getFirstName() + " " + userObj.getLastName());
		model.addAttribute("userId", userObj.getId());
		model.addAttribute("pic", userObj.getProfilePic());
		return "exceptionresolution";
	}

	/**
	 * @param request
	 * @param response
	 */
	private void manageSession(HttpServletRequest request,
			HttpServletResponse response) {
		// Get the current session ID by searching the received cookies.
		String sessionid = null;
		Cookie[] cookies = request.getCookies();
		if (cookies != null) {
			for (int i = 0; i < cookies.length; i++) {
				System.out
						.println("===================>>>>>>>>>>>>>>"
								+ cookies[i].getName() + " || "
								+ cookies[i].getValue());
				if (cookies[i].getName().equals("sessionid")) {
					sessionid = cookies[i].getValue();
					break;
				}
			}
		}

		// If the session ID wasn't sent, generate one.Then be sure to send it
		// to the client with the response.
		// Get the current session ID, or generate one if necessary
		// String sessionid = request.getPathInfo();
		if (sessionid == null) {
			sessionid = generateSessionId();
			Cookie c = new Cookie("sessionid", sessionid);
			response.addCookie(c);

		}
		System.out
				.println("------------------------------------------------------------------------------||");
	}


	// Session Mangement
	// Start
	private static String generateSessionId() {
		String uid = new java.rmi.server.UID().toString(); // guaranteed unique
		return java.net.URLEncoder.encode(uid); // encode any special chars
	}

	// End
	
}